package com.hyts.threads.core;

import com.hyts.threads.conf.ThreadPoolConfig;
import com.hyts.threads.factory.ThreadPoolFactory;
import com.hyts.threads.service.ThreadPoolService;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


/**
 * @author libo
 * @description 线程池管理器
 *
 */
public class ThreadPoolManager {
		
		/**
		 * 构建锁机制
		 */
		private static Lock lock = new ReentrantLock();
	
		/**
		 * 公共单例对象
		 */
		private static ThreadPoolManager manager;
	
		
		/**
		 *  获取实例对象（包含单例以及原型）
		 * @param isSingleTon 是否进行单例
		 * @return
		 */
		public static ThreadPoolManager getInstance(boolean isSingleTon){
						return isSingleTon?manager:new ThreadPoolManager();
		}
		
		/**
		 *  创建线程池（新线程池 构造方法）
		 * @param isLimited 是否无限制缓冲队列：是：类似newCachedThreadPool
		 * @return
		 */
		public ThreadPoolExecutor createThreadPool(boolean isLimited){
				return isLimited?createThreadPool(0,0,0,null, ThreadPoolConfig.DEFAULT_BLOCKQUEUE_SIZE):
						createThreadPool(0,0,0,null,-1);
		}
		
		/**
		 * 创建线程池（新线程池 构造方法）
		 * @param corePoolSize 核心池大小
		 * @param maxPoolSize 最大池大小
		 * @param keepAliveTime 空闲时间
		 * @param unit 时间单位
		 * @param queueSize 缓冲队列大小
		 * @return ThreadPoolExecutor
		 */
		public  ThreadPoolExecutor createThreadPool(int corePoolSize,
											int maxPoolSize,long keepAliveTime,TimeUnit unit,int queueSize){
			lock.lock();
			corePoolSize = corePoolSize == 0 ? ThreadPoolConfig.DEFAULT_CORE_THREAD_POOL_SIZE:corePoolSize;
			maxPoolSize = maxPoolSize == 0 ? ThreadPoolConfig.DEFAULT_MAX_THREAD_POOL_SIZE:maxPoolSize;
			keepAliveTime = keepAliveTime == 0 ? ThreadPoolConfig.DEFAULT_KEEP_ALIVE_TIME:keepAliveTime;
			unit = unit == null ? ThreadPoolConfig.DEFAULT_TIME_UNIT:unit;
			BlockingQueue<Runnable> queue = null;
			if(queueSize > 0)
				queue = new LinkedBlockingQueue<Runnable>();
			else if(queueSize !=0)
				queue = new ArrayBlockingQueue<Runnable>(queueSize);
			else
				queue = new ArrayBlockingQueue<Runnable>(ThreadPoolConfig.DEFAULT_BLOCKQUEUE_SIZE);
				lock.unlock();
			return new ThreadPoolExecutor(corePoolSize,maxPoolSize,keepAliveTime,unit,queue);
		}
		
		/**
		 * 创建线程池（新线程池 构造方法）
		 * @param corePoolSize 核心池大小
		 * @param maxPoolSize 最大池大小
		 * @param keepAliveTime 空闲时间
		 * @param unit 时间单位
		 * @param queueSize 缓冲队列大小
		 * @param factory
		 * @return ThreadPoolExecutor
		 */
		public  ThreadPoolExecutor createThreadPool(int corePoolSize,
				int maxPoolSize,long keepAliveTime,TimeUnit unit,int queueSize,ThreadFactory factory){
				lock.lock();
				corePoolSize = corePoolSize == 0 ? ThreadPoolConfig.DEFAULT_CORE_THREAD_POOL_SIZE:corePoolSize;
				maxPoolSize = maxPoolSize == 0 ? ThreadPoolConfig.DEFAULT_MAX_THREAD_POOL_SIZE:maxPoolSize;
				keepAliveTime = keepAliveTime == 0 ? ThreadPoolConfig.DEFAULT_KEEP_ALIVE_TIME:keepAliveTime;
				unit = unit == null ? ThreadPoolConfig.DEFAULT_TIME_UNIT:unit;
				BlockingQueue<Runnable> queue = null;
				if(queueSize > 0)
					queue = new LinkedBlockingQueue<Runnable>();
				else if(queueSize !=0)
					queue = new ArrayBlockingQueue<Runnable>(queueSize);
				else
					queue = new ArrayBlockingQueue<Runnable>(ThreadPoolConfig.DEFAULT_BLOCKQUEUE_SIZE);
				factory = factory == null ? Executors.defaultThreadFactory():factory;
				lock.unlock();
				return new ThreadPoolExecutor(corePoolSize,maxPoolSize,keepAliveTime,unit,queue,factory);
		}
		
		/**
		 * 创建线程池（新线程池 构造方法）
		 * @param corePoolSize 核心池大小
		 * @param maxPoolSize 最大池大小
		 * @param keepAliveTime 空闲时间
		 * @param unit 时间单位
		 * @param queueSize 缓冲队列大小
		 * @param handler
		 * @return ThreadPoolExecutor
		 */
		public  ThreadPoolExecutor createThreadPool(int corePoolSize,
				int maxPoolSize,long keepAliveTime,TimeUnit unit,int queueSize,RejectedExecutionHandler handler){
				lock.lock();
				corePoolSize = corePoolSize == 0 ? ThreadPoolConfig.DEFAULT_CORE_THREAD_POOL_SIZE:corePoolSize;
				maxPoolSize = maxPoolSize == 0 ? ThreadPoolConfig.DEFAULT_MAX_THREAD_POOL_SIZE:maxPoolSize;
				keepAliveTime = keepAliveTime == 0 ? ThreadPoolConfig.DEFAULT_KEEP_ALIVE_TIME:keepAliveTime;
				unit = unit == null ? ThreadPoolConfig.DEFAULT_TIME_UNIT:unit;
				BlockingQueue<Runnable> queue = null;
				if(queueSize > 0)
					queue = new LinkedBlockingQueue<Runnable>();
				else if(queueSize !=0)
					queue = new ArrayBlockingQueue<Runnable>(queueSize);
				else
					queue = new ArrayBlockingQueue<Runnable>(ThreadPoolConfig.DEFAULT_BLOCKQUEUE_SIZE);
				lock.unlock();
				if(handler == null)
					return new ThreadPoolExecutor(corePoolSize,maxPoolSize,keepAliveTime,unit,queue);
				else	
					return new ThreadPoolExecutor(corePoolSize,maxPoolSize,keepAliveTime,unit,queue,handler);
		}
		
		/**
		 * 创建线程池（新线程池 构造方法）
		 * @param corePoolSize 核心池大小
		 * @param maxPoolSize 最大池大小
		 * @param keepAliveTime 空闲时间
		 * @param unit 时间单位
		 * @param queueSize 缓冲队列大小
		 * @param factory
		 * @param handler
		 * @return
		 */
		public  ThreadPoolExecutor createThreadPool(int corePoolSize,
				int maxPoolSize,long keepAliveTime,TimeUnit unit,int queueSize,ThreadFactory factory,RejectedExecutionHandler handler){
				lock.lock();
				corePoolSize = corePoolSize == 0 ? ThreadPoolConfig.DEFAULT_CORE_THREAD_POOL_SIZE:corePoolSize;
				maxPoolSize = maxPoolSize == 0 ? ThreadPoolConfig.DEFAULT_MAX_THREAD_POOL_SIZE:maxPoolSize;
				keepAliveTime = keepAliveTime == 0 ? ThreadPoolConfig.DEFAULT_KEEP_ALIVE_TIME:keepAliveTime;
				unit = unit == null ? ThreadPoolConfig.DEFAULT_TIME_UNIT:unit;
				BlockingQueue<Runnable> queue = null;
				if(queueSize > 0)
					queue = new LinkedBlockingQueue<Runnable>();
				else if(queueSize !=0)
					queue = new ArrayBlockingQueue<Runnable>(queueSize);
				else
					queue = new ArrayBlockingQueue<Runnable>(ThreadPoolConfig.DEFAULT_BLOCKQUEUE_SIZE);
				factory = factory == null ? Executors.defaultThreadFactory():factory;
				lock.unlock();
				if(handler == null)
					return new ThreadPoolExecutor(corePoolSize,maxPoolSize,keepAliveTime,unit,queue);
				else	
					return new ThreadPoolExecutor(corePoolSize,maxPoolSize,keepAliveTime,unit,queue,factory,handler);
		}
	
		/**
		 * @description 创建线程池
		 * @param service 业务逻辑借口实现类
		 * @return
		 */
		public <T>ThreadPoolExecutor createThreadPool(ThreadPoolService<T> service){
				return ThreadPoolFactory.createTaskPool(service);
		}
	
		/**
		 * @param service 业务逻辑借口实现类
		 * @param isLimited 是否限制
		 * @return
		 */
		public <T>ThreadPoolExecutor createThreadPool(ThreadPoolService<T> service, boolean isLimited){
			return ThreadPoolFactory.createTaskPool(service,isLimited);
		}
		
		/**
		 * @param service 业务逻辑借口实现类
		 * @param param 基本参数对象
		 * @param isLimited 是否限制
		 * @return
		 */
		public <T>ThreadPoolExecutor createThreadPool(ThreadPoolService<T> service,T param,boolean isLimited){
			return ThreadPoolFactory.createTaskPool(service,param,isLimited);
		}
		
		/**
		 * @param service
		 * @return
		 */
		public static boolean kill(ThreadPoolExecutor service){
			if(service == null)
				return false;
			else if(!service.isShutdown()){
				service.shutdown();
				return true;
			}
			else{
				return true;
			}
	} 
		
}
